/*
 * Copyright (C) 2011 Michael Widmer <widmm8@bfh.ch>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package ch.bfh.aeneas.navigation.track;

import android.content.Intent;
import android.location.Location;
import android.os.Binder;
import android.util.Log;
import ch.bfh.aeneas.exchange.intent.AeneasIntent;
import ch.bfh.aeneas.exchange.intent.MalformedIntentException;
import ch.bfh.aeneas.exchange.data.Node;
import ch.bfh.aeneas.exchange.data.Route;
import ch.bfh.aeneas.exchange.data.TrackStorage;
import ch.bfh.aeneas.navigation.app.NavigationService;
import ch.bfh.aeneas.exchange.Scope;
import java.util.ArrayList;
import java.util.List;

/**
 * This is the backing service of TrackMe. It receives the new location from the
 * activity and adds them to the database. Once the node and once the relation 
 * between the currently tracked route and the node.
 * @author Michael Widmer <widmm8@bfh.ch>
 */
public class TrackService extends NavigationService {

    public class TrackServiceBinder extends Binder {

        public TrackService getService() {
            return TrackService.this;
        }
    }
    private final TrackServiceBinder mBinder = new TrackServiceBinder();
    
    private String LOG_TAG = "TrackService";
    private String mCurrentRouteName;
    private Node mLastAddedNode;
    private List<TrackStorage> mStorages;
    private List<Route> mRoutes;
    private int mNodeCounter;
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onCreate() {
        super.onCreate();
        Log.i(LOG_TAG, "TrackService created!");
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onDestroy() {
        Log.i(LOG_TAG, "TrackService destroyed!");
        super.onDestroy();
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    protected void onRequestClosed(int id) {
        
        Log.i(LOG_TAG, "closed request: "+id);
        
        Route r;
        for(int i = 0; i < mStorages.size(); i++) {
            r = mStorages.get(i).addRoute(mCurrentRouteName);
            mRoutes.add(r);
        }
        
        Log.i(LOG_TAG, "serving "+mRoutes.size()+" routes!");
        
        super.setReady();
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    protected void onAnswer(Intent i) {
        Log.i(LOG_TAG, "received answer!");
        if(i.hasExtra("storage")) {
            Log.i(LOG_TAG, "And it even has a storage!");
            TrackStorage s = (TrackStorage) i.getParcelableExtra("storage");
            mStorages.add(s);
        }
    }
    
    public void startTracking(String routeName) {
        
        Log.i(LOG_TAG, "Start tracking route "+routeName);
        
        mCurrentRouteName = routeName;
        
        mStorages = new ArrayList<TrackStorage>();
        mRoutes = new ArrayList<Route>();
        mNodeCounter = 0;
        
        Intent i = super.getBroadcastIntent(AeneasIntent.ACTION_REQUEST, AeneasIntent.CATEGORY_TRACKSTORAGE);
        i.putExtra("scope", Scope.LOCAL);
        i.putExtra("type", "storage");
        
        long timeout = 10000L;
        try {
            super.broadcast(i, timeout);
        } catch (MalformedIntentException ex) {
            Log.i(LOG_TAG, "Error while trying to start new route!");
        }
    }
    
    public void stopTracking() {
        
    }
    
    public void addWayPoint(Location loc) {
        
        Log.i(LOG_TAG, "Adding waypoint to storage: "+mStorages);
        
        //TOTO: enhance filtering of nodes based on range-comparison and/or interpolation
        if(mLastAddedNode == null || mLastAddedNode.getLatitude() != loc.getLatitude() || mLastAddedNode.getLongitude() != loc.getLongitude()) {
        
            Route r;
            Node n;
            for(int i = 0; i < mStorages.size(); i++) {
                r = mRoutes.get(i);
                if(r != null) {
                    n = mStorages.get(i).addNode("node"+Integer.toString(mNodeCounter++), loc);
                    mLastAddedNode = n;
                    if(n != null) {
                        mStorages.get(i).addRouteNode(r, n);
                        //r.addNode(n);
                    } else {
                        Log.e(LOG_TAG, "Created node is null!");
                    }
                } else {
                    Log.e(LOG_TAG, "Created route is null!");
                }
            }

            if(mRoutes.size() > 0) {
                r = mRoutes.get(0);
                Log.i(LOG_TAG, "Now contained "+r.getNodeCount()+" nodes!");
            }
        }
    }
}
